package example.simple_mindmap.common.aop;


import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import example.simple_mindmap.common.annotation.Log;
import example.simple_mindmap.common.domain.po.LogInfo;
import example.simple_mindmap.common.mapper.LogMapper;
import example.simple_mindmap.common.utils.SessionHolder;
import lombok.RequiredArgsConstructor;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.Date;

@Component
@Aspect   //切面类
@RequiredArgsConstructor
public class SysAspect extends ServiceImpl<LogMapper,LogInfo> {

//    @Pointcut("@annotation(io.swagger.annotations.ApiOperation)")
//    private void pointcut() {
//
//    }
    @Pointcut("@annotation(example.simple_mindmap.common.annotation.Log)")
    private void pointcut() {

    }


    @Around("pointcut()")
    public Object around(ProceedingJoinPoint joinPoint)  {
        LogInfo logInfo = new LogInfo();
        //获取用户名
        Long uid = SessionHolder.getUser();
        logInfo.setUid(uid);
        //获取被增强类和方法的信息
        Signature signature = joinPoint.getSignature();
        MethodSignature methodSignature = (MethodSignature) signature;
        //获取被增强的方法对象
        Method method = methodSignature.getMethod();
        //从方法中解析注解
        if(method != null){
            Log logAnnotation = method.getAnnotation(Log.class);
            logInfo.setLog(logAnnotation.name());
//            ApiOperation logAnnotation = method.getAnnotation(ApiOperation.class);
//            logInfo.setLog(logAnnotation.value());
        }
        //方法名字
        String name = method.getName();
        logInfo.setMethod(name);

        //通过工具类获取Request对象
        RequestAttributes reqa = RequestContextHolder.getRequestAttributes();
        ServletRequestAttributes sra = (ServletRequestAttributes)reqa;
        HttpServletRequest request = sra.getRequest();
        //访问的url
        String url = request.getRequestURI().toString();
        logInfo.setUrl(url);
        //请求方式
        String methodName = request.getMethod();
        logInfo.setRequestMethod(methodName);

        //登录IP
        String ipAddr = getIpAddr(request);
        logInfo.setIp(ipAddr);

        //操作发生的时间
        logInfo.setCreateTime(new Date());

        long startTime = System.currentTimeMillis();
        Object obj = null;
        try {
            obj = joinPoint.proceed();
        } catch (Throwable e) {
            logInfo.setDuration(0L);
            save(logInfo);
        }
        long endTime = System.currentTimeMillis();
        //操作持续的时间
        logInfo.setDuration(endTime-startTime);
        //保存到数据库（操作日志）
        save(logInfo);
        return obj;
    }

    /**
     * 获取ip地址
     * @param request
     * @return
     */
    public String getIpAddr(HttpServletRequest request){
        String ip = request.getHeader("x-forwarded-for");
        if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)){
            ip = request.getHeader("Proxy-Client-IP");
        }
        if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)){
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)){
            ip = request.getRemoteAddr();
        }

        return "0:0:0:0:0:0:0:1".equals(ip) ? "127.0.0.1" : ip;
    }

}
